/////////////////////////////////////////////////////////////////////////////
// Original code from libhdfs3. Copyright (c) 2013 - 2014, Pivotal Inc.
// All rights reserved. Author: Zhanwei Wang
/////////////////////////////////////////////////////////////////////////////
//  Modifications by Kumo Inc.
// Copyright (C) Kumo inc. and its affiliates.
// Author: Jeff.li lijippy@163.com
// All rights reserved.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published
// by the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program.  If not, see <https://www.gnu.org/licenses/>.
//



#ifndef _HDFS_LIBHDFS3_COMMON_THREAD_H_
#define _HDFS_LIBHDFS3_COMMON_THREAD_H_

#include <signal.h>


#include <thread>
#include <mutex>
#include <condition_variable>

namespace Hdfs {
namespace Internal {

using std::thread;
using std::mutex;
using std::lock_guard;
using std::unique_lock;
using std::condition_variable;
using std::defer_lock_t;
using std::once_flag;
using std::call_once;
using namespace std::this_thread;

}
}

namespace Hdfs {
namespace Internal {

/*
 * make the background thread ignore these signals (which should allow that
 * they be delivered to the main thread)
 */
sigset_t ThreadBlockSignal();

/*
 * Restore previous signals.
 */
void ThreadUnBlockSignal(sigset_t sigs);

}
}

#define CREATE_THREAD(retval, fun) \
    do { \
        sigset_t sigs = Hdfs::Internal::ThreadBlockSignal(); \
        try { \
            retval = Hdfs::Internal::thread(fun); \
            Hdfs::Internal::ThreadUnBlockSignal(sigs); \
        } catch (...) { \
            Hdfs::Internal::ThreadUnBlockSignal(sigs); \
            throw; \
        } \
    } while(0)

#endif /* _HDFS_LIBHDFS3_COMMON_THREAD_H_ */
